package com.yklx.youke.controller;

import com.yklx.youke.entity.User;
import com.yklx.youke.service.UserService;
import com.yklx.youke.service.MfaService;
import com.yklx.util.JwtUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/auth")
@CrossOrigin(origins = "*")
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final UserService userService;
    private final JwtUtil jwtUtil;
    private final MfaService mfaService;

    public AuthController(AuthenticationManager authenticationManager, UserService userService, JwtUtil jwtUtil, MfaService mfaService) {
        this.authenticationManager = authenticationManager;
        this.userService = userService;
        this.jwtUtil = jwtUtil;
        this.mfaService = mfaService;
    }

    @PostMapping("/register")
    public ResponseEntity<?> registerUser(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String email = request.get("email");
        String password = request.get("password");
        String roleId = request.get("roleId"); // 角色ID而不是角色枚举

        try {
            User registeredUser = userService.registerUser(username, email, password, roleId);
            if (registeredUser == null) {
                return ResponseEntity.status(401).body(Map.of("error", "User registration failed"));
            }
            final String token = jwtUtil.generateToken(registeredUser.getUserId().toString(), registeredUser.getUsername());
            
            Map<String, Object> response = new HashMap<>();
            response.put("userId", registeredUser.getUserId());
            response.put("token", token);
            response.put("refreshToken", null); // Refresh token implementation would go here
            response.put("user", registeredUser);
            
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    @PostMapping("/login")
    public ResponseEntity<?> loginUser(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String password = request.get("password");

        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );
        } catch (BadCredentialsException e) {
            return ResponseEntity.status(401).body(Map.of("error", "Invalid credentials"));
        }

        final User user = userService.findByUsername(username);
        if (user == null) {
            return ResponseEntity.status(401).body(Map.of("error", "User not found"));
        }
        
        // 获取用户详细信息并写入Redis
        org.springframework.security.core.userdetails.UserDetails userDetails = userService.loadUserByUsername(username);
        userService.cacheUserDetails(username, userDetails);
        
        final String token = jwtUtil.generateToken(user.getUserId().toString(), user.getUsername());

        Map<String, Object> response = new HashMap<>();
        response.put("token", token);
        response.put("refreshToken", null); // Refresh token implementation would go here
        response.put("user", user);

        return ResponseEntity.ok(response);
    }

    @PostMapping("/refresh")
    public ResponseEntity<?> refreshToken(@RequestBody Map<String, String> request) {
        String refreshToken = request.get("refreshToken");
        // TODO: Implement refresh token logic
        return ResponseEntity.status(501).body(Map.of("error", "Refresh token not implemented yet"));
    }

    @PostMapping("/logout")
    public ResponseEntity<?> logout(@RequestBody Map<String, String> request) {
        // In a real implementation, we would blacklist the token
        return ResponseEntity.ok(Map.of("success", true));
    }

    @GetMapping("/profile")
    public ResponseEntity<?> getUserProfile() {
        // This would normally get the authenticated user from the security context
        // For now, returning a placeholder response
        return ResponseEntity.ok(Map.of("message", "Profile endpoint placeholder"));
    }

    @PostMapping("/mfa/setup")
    public ResponseEntity<?> setupMfa(@RequestHeader("Authorization") String token) {
        // In a real implementation, this would get the user from the security context
        // For now, returning a placeholder response
        Map<String, Object> response = mfaService.setupMfa(null);
        return ResponseEntity.ok(response);
    }

    @PostMapping("/mfa/verify")
    public ResponseEntity<?> verifyMfa(@RequestBody Map<String, String> request) {
        String code = request.get("code");
        String backupCode = request.get("backupCode");
        String secret = request.get("secret"); // In a real implementation, this would be retrieved from user data

        boolean isValid = mfaService.validateMfa(secret, code, backupCode);
        
        if (isValid) {
            return ResponseEntity.ok(Map.of("valid", true));
        } else {
            return ResponseEntity.status(401).body(Map.of("valid", false, "error", "Invalid MFA code"));
        }
    }
}